<?php

namespace app\index\controller;

use think\Controller;
use think\facade\Request;

class Search extends Controller
{
    protected $currentPage;
    protected $lastPage;
    protected $url;
    protected $word;
    protected $page_num;

    public function __construct()
    {
        //检查前置项,应用地址
        $host = config('app_host');
        if(!$host) {
            $this->error("请配置应用地址【config/app.php文件中】");
        }
        //参数
        $data = Request::route();
        //搜索词 校验及处理
        if(!$data['keyword']) {
            echo '请输入搜索关键词';
            die;
        }
        //特殊符号去除
        $keyword = $this->str($data['keyword']);
        //截取前30个字符
        $this->word = mb_substr($keyword, 0, 30);
        //截取搜索词前30个字符
        $this->word = substr($this->word, 0, 30);
        //页数
        $this->currentPage = isset($data['page']) ? $data['page'] : 1;
        $this->url         = $host . '/search-' . $this->word;
        //每页条数
        $this->page_num = 10;
    }

    /**
     * 字符串中特殊符号去除
     * @param $str string 字符串
     * @return mixed
     */
    public function str($str)
    {
        $find = [ '。', '！', '？', '｡', '＂', '＃', '＄', '％', '＆', '＇', '（', '）', '＊', '＋', '，', '－', '／', '：', '；', '＜', '＝', '＞', '＠', '［', '＼', '］', '＾', '', '', '｛', '｜', '｝', '～', '｟', '｠', '｢', '｣', '､', '、', '〃', '》', '「', '」', '『', '』', '【', '】', '〔', '〕', '〖', '〗', '〘', '〙', '〚', '〛', '〜', '〝', '〞', '〟', '〰', '〾', '〿', '–', '—', '‘', '“', '”', '„', '‟', '…', '‧' ];
        $res  = str_replace($find, [], $str);
        return $res;
    }

    /**
     * 搜索
     * @return \think\response\View
     */
    public function index()
    {
        require_once '/usr/local/xunsearch/sdk/php/lib/XS.php';
        $search = new \XS('demo');   // 自动使用 /usr/local/xunsearch/sdk/php/app/demo.in
        //作项目配置文件
        $search = $search->search; //获取 搜索对象
        $search->setQuery($this->word); // 设置搜索语句
        //$search->addWeight('title', '移民'); // 增加附加条件：提升标题中包含 'xunsearch' 的记录的权重
        $count = $search->count(); // 获取搜索结果的匹配总数估算值
        //跳转到最后,再次获取总条数
        $max_page = ceil($count / $this->page_num);
        $begin    = ($max_page - 1) * $this->page_num;
        $search->setLimit($this->page_num, $begin);
        $search->search();
        $count = $search->count();
        //回到正常分页
        $search->setLimit($this->page_num, ($this->currentPage - 1) * $this->page_num);
        $docs = $search->search();


        //获取搜索结果
        $result = [];
        foreach($docs as $doc) {
            $arr             = [];
            $arr['id']       = $doc->id;
            $arr['title']    = $search->highlight($doc->title);
            $arr['litpic']   = $doc->litpic;
            $arr['true_url'] = $doc->true_url;
            $arr['desc']     = $doc->desc;
            $arr['addtime']  = $doc->addtime;
            $arr['likenum']  = $doc->likenum;
            $arr['views']    = $doc->views;
            $result[]        = $arr;
        }

        // 获取 10 个相关的搜索词
        $words = $search->getRelatedQuery($this->word, 10);
        //设置分页
        if($count < $this->page_num) {
            $page = '';
        } else {
            $page = $this->pageHtml($count);
        }
        return view('/list', [
            'data'  => $result,
            'word'  => $this->word,
            'count' => $count,
            'page'  => $page,
            'hot'   => $words
        ]);
    }

    /**
     * 分页
     * @param $count
     * @return string
     */
    public function pageHtml($count)
    {
        return sprintf(
            '<ul class="pagination">%s %s %s</ul>',
            $this->getPreviousButton(),
            $this->getLinks($count),
            $this->getNextButton($count)
        );
    }

    /**
     * 上一页按钮
     * @return string
     */
    protected function getPreviousButton()
    {
        if($this->currentPage <= 1) {
            return '<li class="disabled"><span>上一页</span></li>';
        }
        if($this->currentPage == 2) {
            return '<li><a href="' . $this->url . '.html">上一页</a></li>';
        }
        return '<li><a href="' . $this->url . '-' . ($this->currentPage - 1) . '.html">上一页</a></li>';
    }

    /**
     * 下一页按钮
     * @param $count int
     * @return string
     */
    protected function getNextButton($count)
    {
        $this->lastPage = floor($count / $this->page_num);
        if($this->currentPage >= $this->lastPage) {
            return '<li class="disabled"><span>下一页</span></li>';
        }
        return '<li><a href="' . $this->url . '-' . ($this->currentPage + 1) . '.html">下一页</a></li>';
    }

    /**
     * 获取中间链接
     * @param $count
     * @return string
     */
    protected function getLinks($count)
    {
        $block          = [
            'first'  => null,
            'slider' => null,
            'last'   => null,
        ];
        $side           = 3;
        $window         = $side * 2;
        $this->lastPage = floor($count / $this->page_num);
        if($this->lastPage < $window + 6) {
            $block['first'] = $this->getUrlRange(1, $this->lastPage);
        } else if($this->currentPage <= $window) {
            $block['first'] = $this->getUrlRange(1, $window + 2);
            $block['last']  = $this->getUrlRange($this->lastPage - 1, $this->lastPage);
        } else if($this->currentPage > ($this->lastPage - $window)) {
            $block['first'] = $this->getUrlRange(1, 2);
            $block['last']  = $this->getUrlRange($this->lastPage - ($window + 2), $this->lastPage);
        } else {
            $block['first']  = $this->getUrlRange(1, 2);
            $block['slider'] = $this->getUrlRange($this->currentPage - $side, $this->currentPage + $side);
            $block['last']   = $this->getUrlRange($this->lastPage - 1, $this->lastPage);
        }

        $html = '';

        if(is_array($block['first'])) {
            $html .= $this->getUrlLinks($block['first']);
        }

        if(is_array($block['slider'])) {
            $html .= $this->getDots();
            $html .= $this->getUrlLinks($block['slider']);
        }

        if(is_array($block['last'])) {
            $html .= $this->getDots();
            $html .= $this->getUrlLinks($block['last']);
        }

        return $html;
    }

    /**
     * 批量生成页码按钮.
     *
     * @param  array $urls
     * @return string
     */
    protected function getUrlLinks(array $urls)
    {
        $html = '';
        foreach($urls as $page => $url) {
            $html .= $this->getPageLinkWrapper($page);
        }

        return $html;
    }

    /**
     * 生成普通页码按钮
     * @param  int $page
     * @return string
     */
    protected function getPageLinkWrapper($page)
    {
        if($this->currentPage == $page) {
            return '<li class="active"><span>' . $page . '</span></li>';
        }
        if($page == 1) {
            return '<li><a href="' . $this->url . '.html">1</a></li>';
        }
        return '<li><a href="' . $this->url . '-' . $page . '.html">' . $page . '</a></li>';
    }

    /**
     * 生成省略号按钮
     *
     * @return string
     */
    protected function getDots()
    {
        return '<li class="disabled"><span>...</span></li>';
    }

    /**
     * 创建一组分页链接
     *
     * @access public
     * @param  int $start
     * @param  int $end
     * @return array
     */
    public function getUrlRange($start, $end)
    {
        $urls = [];
        for($page = $start; $page <= $end; $page++) {
            $urls[$page] = $this->url . '-' . $page . '.html';
        }
        return $urls;
    }
}
